package com.kindnesslibrary.dialog;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.util.LruCache;
import android.view.View;
import android.widget.ImageView;

import com.kindnesslibrary.R;
import com.kindnesslibrary.activity.XImageActivity;
import com.kindnesslibrary.activity.adapter.XImageAdapter;
import com.kindnesslibrary.base.BaseDialog;
import com.kindnesslibrary.util.Contants;
import com.kindnesslibrary.util.FileUtil;
import com.kindnesslibrary.util.MyUtil;
import com.kindnesslibrary.util.ScreenUtil;
import com.kindnesslibrary.util.ToastUtil;
import com.kindnesslibrary.ximage.XImageLoader;
import com.kindnesslibrary.ximage.XImgSelConfig;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by lenovo on 2017/7/1.
 */
public class ChooseImageDialog extends BaseDialog {

    View rl_choose_image_choose, rl_choose_image_take, rl_choose_image_cancle;
    private File photoPath, outPath;
    private XImgSelConfig xImgSelConfig;
    private Activity context;

    private OnImageDialogListener onImageDialogListener;
    private LruCache<String, Bitmap> mMemoryCache;

    public OnChooseImageListener onChooseImageListener = new OnChooseImageListener() {

        @Override
        public void camera() {
            photoPath = startCamera(Contants.CAMERA_CODE_RESULT);
        }

        @Override
        public void cameraResult() {
            if (photoPath != null && photoPath.exists()) {
                if(xImgSelConfig != null && xImgSelConfig.needCrop){
                    String sf = new StringBuffer(photoPath.getAbsolutePath()).insert(photoPath.getAbsolutePath().lastIndexOf("."), System.currentTimeMillis()).toString();
                    outPath = new File(sf);
                    startPhotoZoom(Contants.CAMERA_CODE_ZOOM, photoPath, outPath);
                }else{
                    if(onImageDialogListener != null){
                        onImageDialogListener.camera(photoPath.getAbsolutePath());
                    }
                }
            }else{
                ToastUtil.showToast("图片不存在");
            }
        }

        @Override
        public void cameraZoom() {
            if (outPath != null && outPath.isFile() && outPath.exists()) {
                if(onImageDialogListener != null){
                    onImageDialogListener.camera(outPath.getAbsolutePath());
                }
            }
        }

        @Override
        public void album(Intent data) {
            ArrayList<String> imageList = (ArrayList<String>) data.getSerializableExtra(Contants.ALBUM_LIST);
            if(onImageDialogListener != null){
                if(xImgSelConfig != null && xImgSelConfig.needCrop){
                    String sf = new StringBuffer(imageList.get(0)).insert(imageList.get(0).lastIndexOf("."), System.currentTimeMillis()).toString();
                    outPath = new File(sf);
                    startPhotoZoom(Contants.CAMERA_CODE_ZOOM, new File(imageList.get(0)), outPath);
                }else {
                    onImageDialogListener.album(imageList);
                }
            }
        }
    };

    public ChooseImageDialog(Activity context, int theme, int width, int height) {
        super(context, theme, width, height);
        this.context = context;
        int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        int cacheMemory = maxMemory / 8;
        mMemoryCache = new LruCache<String, Bitmap>(cacheMemory) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes() * value.getHeight() / 1024;
            }
        };
    }

    @Override
    protected int init() {
        return R.layout.activity_choose_image_layout;
    }

    @Override
    protected void initView(View view) {
        rl_choose_image_choose = view.findViewById(R.id.rl_choose_image_choose);
        rl_choose_image_take = view.findViewById(R.id.rl_choose_image_take);
        rl_choose_image_cancle = view.findViewById(R.id.rl_choose_image_cancle);
    }

    @Override
    protected void setViewData() {

    }

    @Override
    protected void initEvent() {
        rl_choose_image_choose.setOnClickListener(view -> {
            if(xImgSelConfig == null) {
                xImgSelConfig = new XImgSelConfig.Builder(xImageLoader).maxNum(9).showCamera(true).isCrop(true).isPreview().build();
                XImageActivity.open(context, xImgSelConfig, Contants.ALBUM_CONTENT_DATA_CODE);
            }else{
                XImageActivity.open(context, xImgSelConfig.setImageLoader(xImageLoader), Contants.ALBUM_CONTENT_DATA_CODE);
            }
            dismiss();
        });
        rl_choose_image_take.setOnClickListener(view -> {
            photoPath = startCamera(Contants.CAMERA_CODE_RESULT);
            dismiss();
        });
        rl_choose_image_cancle.setOnClickListener(view -> {
            dismiss();
        });
        view.setOnClickListener(v -> dismiss());
    }

    @Override
    protected void getData() {

    }

    @Override
    public void onClick(View v) {

    }

    /**
     * 启动系统相机并返回拍照图片存储地址
     *
     * @param requestCode
     * @return
     */
    protected File startCamera(int requestCode) {
        // 检查是否包含外部存储
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            // 检查是否包含照相机权限
            if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) !=
                    PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(context, new String[]{
                        Manifest.permission.CAMERA}, Contants.CAMERA_CODE);
                return null;
            }
            File file = new File(Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera");
            if (file == null) {
                ToastUtil.showToast(getString(R.string.device_no_support));
                return null;
            }
            if (!file.exists())
                file.mkdirs();
            file = new File(file.getPath()
                    + "/" + System.currentTimeMillis() + ".jpeg");
            Intent in = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

            Uri fileUri;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                fileUri = FileUtil.getFileProvider(context, file);
                in.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            } else {
                fileUri = Uri.fromFile(file);
            }
            in.putExtra(MediaStore.EXTRA_OUTPUT,
                    fileUri);
            context.startActivityForResult(in, requestCode);
            return file;
        } else {
            ToastUtil.showToast(getString(R.string.device_no_support));
        }
        return null;
    }

    /**
     * 跳转到裁剪图片
     *
     * @param requestCode
     * @param inFile      读取路径
     * @param outFile     裁剪后输出路径
     */
    protected void startPhotoZoom(int requestCode, File inFile, File outFile) {
        if (inFile == null && outFile == null) {
            ToastUtil.showToast(getString(R.string.picture_clipping_failed));
            return;
        }
        Intent intent = new Intent("com.android.camera.action.CROP");
        // 设置裁剪
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        int width = context.getWindowManager().getDefaultDisplay().getWidth() / 2;
        intent.putExtra("outputX", width);
        intent.putExtra("outputY", width);
        intent.putExtra("return-data", false);
        intent.putExtra("noFaceDetection", true);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        Uri inUri, outUri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            inUri = FileUtil.getFileProvider(context, inFile);
        } else {
            inUri = Uri.fromFile(inFile);
        }
        outUri = Uri.fromFile(outFile);
        intent.setDataAndType(inUri, "image/*");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outUri);
        context.startActivityForResult(intent, requestCode);
        context.overridePendingTransition(R.anim.slide_right_in, R.anim.slide_left_out);
    }

    public void setxImgSelConfig(XImgSelConfig xImgSelConfig) {
        this.xImgSelConfig = xImgSelConfig;
    }

    public void setOnImageDialogListener(OnImageDialogListener onImageDialogListener) {
        this.onImageDialogListener = onImageDialogListener;
    }

    XImageLoader xImageLoader = (context, localPath, iv, adapter, index) -> {
        if(getBitmapFromMemoryCache(localPath) == null){
            startRunnable(() -> {
                Bitmap bitmap = MyUtil.getInstance().compressBitmap(getContext(), ScreenUtil.getDialogWidth(getContext()) / 6, ScreenUtil.getDialogWidth(getContext()) / 6, localPath);
                addBitmapToMemoryCache(localPath, bitmap);
                iv.post(() -> {
                    iv.setImageBitmap(bitmap);
                });
            });
        }else{
            iv.setImageBitmap(getBitmapFromMemoryCache(localPath));
        }
    };

    // 往内存缓存中添加bitmap数据
    private void addBitmapToMemoryCache(String key, Bitmap bitmap) {
        if (getBitmapFromMemoryCache(key) == null) {
            mMemoryCache.put(key, bitmap);
        }
    }

    // 从内存缓存中获取Bitmap对象
    private Bitmap getBitmapFromMemoryCache(String key) {
        return mMemoryCache.get(key);
    }

    public interface OnChooseImageListener{
        void camera();
        void cameraResult();
        void cameraZoom();
        void album(Intent data);
    }

    public interface OnImageDialogListener{
        void camera(String path);
        void album(List<String> albumList);
    }

}
